//
// Create by Zeng Yun on 2018/12/20
//

package home

import (
	"adai.design/jarvis/device"
	"adai.design/jarvis/member"
)

// 家庭消息中心
type Hub struct {

	// 所有的家庭
	homes map[string]*Home

	rDevPkg chan *device.MessagePkg
	sDevPkg chan *device.MessagePkg

	rMemberPkg chan *member.MessagePkg
	sMemberPkg chan *member.MessagePkg
}

func (h *Hub) getHome(id string) (*Home, bool) {
	if home, ok := h.homes[id]; ok {
		return home, true
	}

	home := newHome(id)
	if home != nil {
		h.homes[id] = home
		home.run(h)
		return home, true
	}
	return nil, false
}

// 家庭消息调度中心
func (h *Hub) start() {
	member.AddObserver(h)
	device.AddObserver(h)

	defer func() {
		member.RemoveObserver(h)
		device.RemoveObserver(h)
	}()

	for {
		select {

		// 设备发送至家庭中心的消息
		// device >> home
		case pkg, ok := <-h.rDevPkg:
			if ok {
				if home, ok := h.getHome(pkg.HomeId); ok {
					home.containerPkgHandle(pkg)
				}
			}

		// 家庭中心发送至设备的消息
		// home >> device
		case pkg, ok := <-h.sDevPkg:
			if ok {
				device.SendPkg(pkg)
			}

		// 家庭成员发送至家庭中心的消息
		// member >> home
		case pkg, ok := <-h.rMemberPkg:
			if ok {
				if home, ok := h.getHome(pkg.Ctx.HomeId); ok {
					home.memberPkgHandle(pkg)
				}
			}

		// 家庭中心发送给家庭成员的消息
		// home >> member
		case pkg, ok := <-h.sMemberPkg:
			if ok {
				member.SendPackage(pkg)
			}
		}
	}
}

var hub = &Hub{
	homes:      map[string]*Home{},
	rDevPkg:    make(chan *device.MessagePkg, 10),
	sDevPkg:    make(chan *device.MessagePkg, 10),
	rMemberPkg: make(chan *member.MessagePkg, 10),
	sMemberPkg: make(chan *member.MessagePkg, 10),
}

// 成员发送至家庭中心的消息
func (h *Hub) MemberPkgHandler(pkg *member.MessagePkg) {
	h.rMemberPkg <- pkg
}

// 设备发送只家庭中心的消息
func (h *Hub) DevicePkgHandle(pkg *device.MessagePkg) {
	h.rDevPkg <- pkg
}

func Start() {
	hub.start()
	device.AddObserver(hub)
}
